package SGUI

import (
	. "SGEngine2"
	"dom4g"
	"fmt"
	"strings"
)

type TopWidget struct {
	WidgetInfo
	XmlStr        string
	FilePath      string
	WidgetIds     map[string]IWidget
	WidgetClasses map[string]*Array
	SGMLFunc      map[string]SGMLEvent
	ImportWidget  map[string]string
	UserData      interface{}
	WidgetPath    string
}

func (t *TopWidget) OnAttach(node *Node) {

}

func (t *TopWidget) GetWidgetInfo() *WidgetInfo {
	return &t.WidgetInfo
}

func (t *TopWidget) OnDetach(node *Node) {

}

func (t *TopWidget) OnUpdate() {

}

func (this *TopWidget) RegisterEvent(eventName string, event SGMLEvent) {
	this.SGMLFunc[eventName] = event
}

func (this *TopWidget) CallEvent(eventName string, node *Node, funcType string) {
	if funcType == "go" {
		if v, ok := this.SGMLFunc[eventName]; ok {
			v(node)
		}
	} else if funcType == "js" {
		UIScript.JsEngine.Run(eventName)
	}
}

func (t *TopWidget) AddWidgetByXML(elem *dom4g.Element, node *Node, parentw IWidget) {
	var widget IWidget
	widget = t.genWidgetByxml(elem, node, parentw)
	t.cacheIds(elem, widget)
	t.cacheClasses(elem, widget)
	t.AddAttrs(widget, elem)
	if SGMLGlobal.SGMLTypes[elem.Name()].ElemType == SGMLElemType_Custom {
		SGMLGlobal.SGMLTypes[elem.Name()].CustomChildParse(widget, elem)
		node.Add(widget.(IComponent))
		return
	}
	node.Add(widget.(IComponent))
	for i := 0; i < len(elem.AllNodes()); i++ {
		newNode := ZeroNode()
		node.AddChild(newNode)
		t.AddWidgetByXML(elem.AllNodes()[i], newNode, widget)
	}
	if widget != nil {
		widget.OnLoad()
	}
}

func (this *TopWidget) genWidgetByxml(elem *dom4g.Element, node *Node, parentw IWidget) IWidget {
	if v, ok := this.ImportWidget[elem.Name()]; ok {
		Attrs := this.parseTopWidgetAttr(elem, parentw)
		tw := SGMLGlobal.LoadTopWidget(v, Attrs, node, this.WidgetPath+"/"+elem.Name())
		tw.Node = node
		tw.Top = this
		return tw
	}
	widget := SGMLGlobal.SGMLTypes[elem.Name()].GenFunc(elem, node, this, parentw)
	widget.GetWidgetInfo().Top = this
	return widget
}

func (t *TopWidget) parseTopWidgetAttr(elem *dom4g.Element, parent IWidget) map[string]interface{} {
	Attrs := make(map[string]interface{})
	for i := 0; i < len(elem.Attrs); i++ {
		curattr := elem.Attrs[i]
		v := curattr.Value
		if len(v) > 0 && v[0] == '[' {
			NewV := v[1 : len(v)-1]
			Attrs[curattr.Name()] = strings.Split(NewV, " ")
		} else if len(v) > 0 && v[0] == '$' {
			Attrs[curattr.Name()] = t.UserData.(map[string]interface{})[v[1:len(v)-1]]

		} else {
			Attrs[curattr.Name()] = v
		}
	}
	return Attrs
}

func (t *TopWidget) cacheIds(elem *dom4g.Element, widget IWidget) {
	if StrId, b := elem.AttrValue("Id"); b {
		widget.GetWidgetInfo().ID = StrId
		t.WidgetIds[StrId] = widget
	}

}

func (this *TopWidget) cacheClasses(elem *dom4g.Element, widget IWidget) {
	if StrClass, b := elem.AttrValue("Class"); b {
		v, have := this.WidgetClasses[StrClass]
		if !have {
			v = new(Array)
			this.WidgetClasses[StrClass] = v
		}
		v.Add(widget)
	}
}

func (t *TopWidget) GetId(strId string) IWidget {
	return t.WidgetIds[strId]
}

func (this *TopWidget) GetClass(className string) *Array {
	return this.WidgetClasses[className]
}

func (this *TopWidget) AddAttrs(widget IWidget, elem *dom4g.Element) {
	for i := 0; i < len(elem.Attrs); i++ {
		curattr := elem.Attrs[i]
		widget.GetWidgetInfo().AddAttr(curattr.Name(), curattr.Value)
	}
}

func (this *TopWidget) LoadChild(elem *dom4g.Element) {
	ChildName, b := elem.AttrValue("Name")
	if !b {
		fmt.Println("子组件载入出错 必须存在Name")
	}
	filePath, b2 := elem.AttrValue("src")
	if !b2 {
		fmt.Println("子组件载入出错 必须存在src")
	}
	this.ImportWidget[ChildName] = filePath
}
